package com.yxsk.relay.job.admin.web.service;

import com.yxsk.relay.job.admin.data.entity.JobDetails;
import com.yxsk.relay.job.admin.data.repository.JobDetailsRepository;
import com.yxsk.relay.job.admin.web.common.exception.RelayAdminWebRuntimeException;
import com.yxsk.relay.job.admin.web.controller.dto.JobRelationQueryDto;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * @Author 11376
 * @CreaTime 2019/6/26 23:31
 * @Description
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS)
public class AdminJobDetailService extends AdminAbstractService<JobDetails, JobDetailsRepository> {

    @Transactional(propagation = Propagation.REQUIRED)
    public void updateChildrenJob(String id, List<String> children) {
        // 查询任务是否存在
        Optional<JobDetails> optional = this.repository.findById(id);
        if (!optional.isPresent()) {
            throw new RelayAdminWebRuntimeException("未找到相关任务信息");
        }
        // 删除原子任务
        this.repository.deleteAllChildren(id);
        // 添加子任务
        if (!CollectionUtils.isEmpty(children)) {
            children.stream().forEach(childId -> this.repository.addJobRelation(id, childId));
        }
    }

    public JobRelationQueryDto getJobRelation(String jobId) {
        JobRelationQueryDto queryDto = new JobRelationQueryDto();
        Optional<JobDetails> optional = this.repository.findById(jobId);
        if (!optional.isPresent()) {
            throw new RelayAdminWebRuntimeException("未找到任务信息");
        }
        // 临时存放任务id
        Map<String, JobDetails> detailsMap = new HashMap<>();
        // 任务关系
        Map<String, List<String>> relation = new HashMap<>();

        JobDetails details = optional.get();
        detailsMap.put(jobId, details);

        List<String> childrenIds = this.repository.findChildrenIds(details.getId());
        if (!CollectionUtils.isEmpty(childrenIds)) {
            relation.put(jobId, childrenIds);
            putChildren(detailsMap, relation, childrenIds);
        }

        queryDto.setJobs(new LinkedList<>(detailsMap.values()));
        queryDto.setRelation(relation);

        return queryDto;
    }

    private void putChildren(Map<String, JobDetails> detailsMap, Map<String, List<String>> relation, List<String> childrenIds) {
        childrenIds.stream().forEach(id -> {
            if (!detailsMap.containsKey(id)) {
                Optional<JobDetails> optional = this.repository.findById(id);
                if (optional.isPresent()) {
                    JobDetails child = optional.get();
                    detailsMap.put(id, child);
                    List<String> childrenIdList = this.repository.findChildrenIds(id);

                    if (!CollectionUtils.isEmpty(childrenIdList)) {
                        relation.put(id, childrenIdList);
                        putChildren(detailsMap, relation, childrenIdList);
                    }
                }
            }
        });
    }

}
